import _ from 'lodash';
import { getCssVariableValue } from '@/utils/utils';

const bgColor = '#161A1D'; // 背景色/整体背景
const borderColor = '#4E5154'; // 分割线/分割线&边框
const fontColor1 = '#D3D4D4'; // 文本颜色/一级文本
const fontColor2 = '#A7A8A9'; // 文本颜色/二级文本
const fontColor3 = '#7A7D7F'; // 文本颜色/三级文本
const fontDisabled = '#646769'; // 文本颜色/不可点击
const fontSize = 14;

// 轴
const axisBase = {
  x: {
    boundaryGap: true,
    nameGap: 8,
    axisTick: { alignWithLabel: true, length: 4, lineStyle: { color: borderColor } },
    axisLabel: { color: fontColor3 },
    axisLine: { onZero: false, lineStyle: { color: borderColor } },
    splitLine: { show: false },
  },
  y: {
    nameGap: 8,
    nameTextStyle: { fontSize, lineHeight: fontSize, color: fontColor3 },
    axisLabel: { color: fontColor3 },
    axisLine: { show: false },
    axisTick: { show: false },
    splitLine: { lineStyle: { color: borderColor, opacity: 0.5 } },
  },
};

// 图例组件
const legendSvg = {
  line: 'path://M 0 275 L 200 275 A 50 43 0 1 1 600 275 L 800 275 L 800 300 L 550 300 A 50 50 0 1 0 250 300 L 0 300 Z M 0 325 L 200 325 A 50 43 0 1 0 600 325 L 800 325 L 800 300 L 550 300 A 50 50 0 1 1 250 300 L 0 300 Z',
};
const legendBase = {
  type: 'scroll',
  width: '100%',
  bottom: 0,
  itemGap: fontSize,
  itemWidth: 16,
  itemHeight: 8,
  textStyle: { fontSize, lineHeight: fontSize, color: fontColor2 },
  padding: 0,
  borderColor: fontDisabled,
  inactiveBorderColor: fontDisabled,
  inactiveBorderWidth: 1,
  inactiveColor: fontDisabled,
};

// 提示框组件
const tooltipBase = {
  show: true,
  confine: true,
  enterable: false,
  trigger: 'axis',
  axisPointer: {
    type: 'line',
    lineStyle: { width: 1, color: borderColor, type: 'solid' },
  },
  backgroundColor: bgColor,
  borderWidth: 0,
  padding: [fontSize, fontSize],
  textStyle: { fontSize, lineHeight: fontSize, color: fontColor2 },
  position: function (point, params, dom, rect, size) {
    let x = 0;
    const offset = 0;
    const [pointX] = point; // 鼠标位置
    const [viewW] = size.viewSize; // 外层div大小
    const [boxW] = size.contentSize; // 提示框宽度
    // boxW > pointX 说明鼠标左边放不下提示框
    if (pointX > viewW / 2) {
      x = pointX - boxW - offset;
    } else {
      x = pointX + offset;
    }
    return [x, 0];
  },
};

// 区域缩放
const sliderBase = {
  type: 'slider',
  brushSelect: false,
  show: true,
  showDetail: false,
  bottom: 26,
  start: 0,
  end: 100,
  height: 20,
  backgroundColor: getCssVariableValue('--bg-form'),
  dataBackground: {
    dataBackground: {
      areaStyle: { opacity: 0 },
      lineStyle: { opacity: 0 },
    },
  },
  selectedDataBackground: {
    areaStyle: {
      color: getCssVariableValue('--font-primary'),
      opacity: 0.15,
    },
    lineStyle: { color: 'transparent' },
  },
  borderColor: 'transparent',
  handleStyle: {
    color: getCssVariableValue('--bg-form'),
    borderColor: getCssVariableValue('--bd'),
  },
};

// 获取系列配置 { type, name, color } 必填可正常展示；其他合并属性使用props字段
const getSeries = ({ type, name, borderColor, color, data, props }) => {
  let temp = {};
  temp.name = name;
  temp.itemStyle = { color };
  if (!!borderColor) temp.itemStyle.borderColor = borderColor;
  if (!!data) temp.data = [...data];
  // 增加虚线类型
  if (type === 'line' || type === 'dashed') {
    temp.type = 'line';
    temp.symbol = 'none';
    temp.lineStyle = { type, width: 1 };
    temp.emphasis = { lineStyle: { type, width: 1 } };
  } else {
    temp.type = type;
  }
  // 其他特殊样式
  if (type === 'bar') {
    temp.barMaxWidth = 20;
  }
  if (type === 'boxplot') {
    temp.boxWidth = ['10%', '100%'];
  }
  return {
    ...temp,
    ...(props || {}),
  };
};

// 根据系列配置=>获取图例配置
const getLegend = ({ type, name }) => {
  let temp = { name };
  if (legendSvg[type]) temp.icon = legendSvg[type];
  if (type === 'dashed') {
    temp.itemStyle = { opacity: 0 };
    temp.lineStyle = { width: 2 };
  }
  return temp;
};

// 获取轴配置 type必填：category类目 value值，formatter外提
const getAxis = (arr = [], direc) => {
  return arr.map((x) => {
    const { name, type, data, formatter, ...others } = x;
    let temp = _.cloneDeep(axisBase[direc]);
    if (!!type) temp.type = type;
    if (!!name) temp.name = name;
    if (!!data) temp.data = data;
    if (!!formatter) temp.axisLabel.formatter = formatter;
    return { ...temp, ...others };
  });
};

// 时间线，需要配合{ baseOption, options}使用，参考官方文档
const timelineBase = {
  axisType: 'category',
  orient: 'vertical',
  autoPlay: false,
  inverse: true,
  playInterval: 3000,
  padding: 0,
  right: 0,
  top: 30,
  bottom: 24,
  width: 48,
  symbol: 'none',
  label: { color: fontColor2 },
  checkpointStyle: { symbolSize: 10, borderWidth: 2, color: '#fff', borderColor: '#18A0FB' },
  controlStyle: { itemSize: 13, showNextBtn: false, showPrevBtn: false },
  lineStyle: { show: true, color: borderColor, width: 1, type: 'solid' },
  itemStyle: { color: '#fff' },
  progress: {
    lineStyle: { color: borderColor },
    label: { color: fontColor2, opacity: 0.5 },
  },
};

const formatterGrid2 = (params) => {
  // 双grid tooltip
  let content = [];
  params.map((x) => {
    const { marker, seriesName, dimensionNames, encode, data, axisIndex } = x;
    let value = typeof data === 'object' ? data[dimensionNames[encode.y[0]]] : data;
    if (typeof value === 'undefined') value = '-';
    if (!content[axisIndex]) content[axisIndex] = '';
    content[axisIndex] += `<div style="display:flex;align-items:center;">${marker}
                            <div style="flex:1;display:flex;align-items:center;justify-content:space-between;">
                              <span style="color:${fontColor2};">${seriesName}</span>
                              <span style="color:${fontColor1};margin-left:8px;">${value}</span>
                            </div>
                          </div>`;
  });
  const sline = `<div style="width:100%;height:1px;background:${borderColor};margin:4px 0"></div>`;
  return `<div style="color:${fontColor3};">${params?.[0]?.axisValue || ''}</div>
          <div>${content.join(sline)}</div>`;
};

/**
 * 缩减传入配置
 */
export default (option) => {
  if (!option) return null;
  // 1. 自定义
  if (option.diy === true) return option || null;
  // 2. 使用通用配置
  const {
    title,
    grid, // *
    xAxis = [],
    yAxis = [],
    dataset, // obj
    legend, // obj
    tooltip, // obj
    series = [],
    timeline, // obj { title: '时间线', data: [], options: [] }
    dataZoomInside = false, // 内部滚动
    dataZoomSlider = false, // 外部滚动
    axisPointer,
    animation = true,
  } = option;
  // 初始化基础配置
  let baseOption = {};
  baseOption.xAxis = getAxis(xAxis, 'x');
  baseOption.yAxis = getAxis(yAxis, 'y');
  baseOption.animation = animation;
  if (!!title) baseOption.title = title;
  if (!!grid) baseOption.grid = grid;
  if (!!dataset) baseOption.dataset = dataset;
  if (!!axisPointer)
    baseOption.axisPointer = {
      link: [{ xAxisIndex: 'all' }],
      lineStyle: { color: borderColor, type: 'solid' },
    };
  if (series?.length > 0) {
    // 系列&提示框组件
    let legendData = [];
    baseOption.series = series.map((x) => {
      legendData.push(getLegend(x));
      return getSeries(x);
    });
    if (!!legend) {
      baseOption.legend = {
        data: legendData,
        ...legendBase,
        ...(legend || {}),
      };
    }
  }
  if (!!tooltip) {
    // 图例组件
    baseOption.tooltip = {
      ...tooltipBase,
      ...(tooltip || {}),
    };
    if (!!axisPointer) baseOption.tooltip.formatter = formatterGrid2;
  }
  // 区域缩放
  if (option.dataZoom) {
    baseOption.dataZoom = option.dataZoom;
  } else {
    if (dataZoomInside || dataZoomSlider) {
      baseOption.dataZoom = [];
      dataZoomInside === true &&
        baseOption.dataZoom.push({
          type: 'inside',
        });
      const lastGrid = grid?.length ? grid?.[grid.length - 1] : grid;
      dataZoomSlider === true &&
        baseOption.dataZoom.push({
          ...sliderBase,
          left: lastGrid.left || 0,
          right: !!timeline ? timelineBase.width + 24 : lastGrid.right || 10,
          xAxisIndex: Array.from({ length: grid?.length || 1 }).map((__, i) => i),
        });
    }
  }

  if (!!timeline) {
    // 右侧时间线
    if (!!timeline?.title) {
      baseOption.title = {
        text: timeline.title,
        top: 0,
        right: 0,
        textStyle: { color: fontColor1, fontSize: fontSize, lineHeight: fontSize },
      };
    }
    return {
      baseOption: {
        ...baseOption,
        timeline: {
          ...timelineBase,
          data: timeline?.data || [],
        },
      },
      options: timeline?.options || [],
    };
  }
  return baseOption;
};
